/*
 * Copyright (c) 2018-2023 北京华恒盛世科技有限公司
 * QUICKPOOL is licensed under Mulan PSL v2.
 * You can use this software according to the terms and conditions of the Mulan PSL v2.
 * You may obtain a copy of Mulan PSL v2 at:
 *     http://license.coscl.org.cn/MulanPSL2
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 * See the Mulan PSL v2 for more details.
*/

#ifndef QUICKPOOL_API_H
#define QUICKPOOL_API_H

#include "limit.h"
#include "xdrbase.h"
#include "hash.h"
#include "common.h"
#include "lib.h"

#define GET_LOW(s, word)  (s = word & 0x0000ffff)
#define GET_HIGH(s, word) (s = (word >> 16) & 0x0000ffff)

#define MAX_GROUPS          1024

#define LOST_QUEUE  ((char *)"lost_queue")
#define LOST_NODE  ((char *)"lost_node")
#define EMPTY_STRING    ((char *)"")
#define DEFAULT_STRING  ((char *)"default")
#define ALL_STRING ((char *)"all")

/* MACRO for default value of QuickPool parameters */ 
#define DELETE_NUMBER     -2
#define DEL_NUMPRO        INFINIT_INT
#define DEFAULT_NUMPRO    INFINIT_INT -1

#define FIRST_HOST_TOKEN '!'

#define DEFAULT_JS_SLEEPTIME          10
#define DEFAULT_JM_SLEEPTIME          10
#define DEFAULT_ACCEPT_INTVL           1
#define DEFAULT_MAX_RETRY              5
#define DEFAULT_MAXJM_FAIL             3
#define DEFAULT_CLEAN_PERIOD        3600
#define DEFAULT_MAX_JOB_NUM         1000
#define DEFAULT_PG_SUSP_IT           180
#define DEFAULT_RETRY_INTVL            2
#define DEFAULT_MAX_JM_CONNS        4096
#define DEFAULT_RUSAGE_UPDATE_RATE     1
#define DEFAULT_RUSAGE_UPDATE_PERCENT 10
#define DEFAULT_SCHEDULE_TIME          3
#define DEFAULT_LOAD_UPDATE_INTERVAL  15
#define DEFAULT_MAX_JOBARRAY_SIZE   1000
#define DEFAULT_JOB_TERM_INTERVAL     10
#define DEFAULT_PRE_EXEC_DELAY        -1
#define DEFAULT_MAX_PREEMPT_JOBS      12
#define DEFAULT_POWER_WAIT_TIME        0
#define DEFAULT_HJOB_PER_SESSION      16

typedef enum {
    PARAM_KEY_DEFAULT_QUEUE=0,
    PARAM_KEY_DEFAULT_PROJECT,
    PARAM_KEY_JS_SLEEP_TIME,
    PARAM_KEY_JM_SLEEP_TIME,
    PARAM_KEY_JOB_ACCEPT_INTERVAL,
    PARAM_KEY_MAX_RETRY,
    PARAM_KEY_MAX_JM_FAIL,
    PARAM_KEY_CLEAN_PERIOD,
    PARAM_KEY_MAX_JOB_NUM,
    PARAM_KEY_PG_SUSP_IT,
    PARAM_KEY_RETRY_INTERVAL,
    PARAM_KEY_MAX_JM_CONNS,
    PARAM_KEY_RUSAGE_UPDATE_RATE,
    PARAM_KEY_RUSAGE_UPDATE_PERCENT,
    PARAM_KEY_MAX_SCHEDULE_TIME,
    PARAM_KEY_LOAD_UPDATE_INTERVAL,
    PARAM_KEY_MAX_JOBID,
    PARAM_KEY_MAX_JOB_ARRAY_SIZE,
    PARAM_KEY_JOB_TERMINATE_INTERVAL,
    PARAM_KEY_JOB_DEP_LAST_SUB,
    PARAM_KEY_MAX_USER_PRIORITY,
    PARAM_KEY_JOB_PRIORITY_OVER_TIME,
    PARAM_KEY_JOB_PRIORITY_VALUE,
    PARAM_KEY_JOB_PRIORITY_TIME,
    PARAM_KEY_RESOURCE_UPDATE_INTERVAL,
    PARAM_KEY_PRE_EXEC_DELAY,
    PARAM_KEY_RESOURCE_RESERVE,
    PARAM_KEY_MAX_ACCT_ARCHIVE_FILE,
    PARAM_KEY_ACCT_ARCHIVE_SIZE,
    PARAM_KEY_ACCT_ARCHIVE_AGE,
    PARAM_KEY_MAX_PREEMPT_JOBS,
    PARAM_KEY_MAX_NUM_CANDIDATES,
    PARAM_KEY_ENABLE_PROXY_HOSTS,
    PARAM_KEY_DISABLE_PEER_JOBS,
    PARAM_KEY_ENABLE_PTILE_PACK,
    PARAM_KEY_MAX_JOB_SCHEDULE,
    PARAM_KEY_HJOB_PER_SESSION,
    PARAM_KEY_RECORD_SWITCH_NOFORK,
    PARAM_KEY_MIGRATE_TOPEND,
    PARAM_KEY_NO_QSORT_JOBS,
    PARAM_KEY_MODIFY_RUNNING_JOB,
    PARAM_KEY_PREEMPT_FOR_REQUEUE,
    PARAM_KEY_MAX_JOB_REQUEUE,
    PARAM_KEY_ALLOW_ROOT_SUBMIT,
    PARAM_KEY_ENABLE_EXCLUSIVE,
    PARAM_KEY_MAX,
} param_setting_t;

extern char **environ;

#define  XF_OP_SUB2EXEC         0x1
#define  XF_OP_EXEC2SUB         0x2
#define  XF_OP_SUB2EXEC_APPEND  0x4
#define  XF_OP_EXEC2SUB_APPEND  0x8

enum submitType {
    CMD_SUBMIT_JOB = 1,
    CMD_MODIFY_JOB,
    CMD_RESTART_JOB,
};

typedef enum {
    BATCH_JOB_SUB       = 1,
    BATCH_JOB_INFO      = 2,
    BATCH_JOB_PEEK      = 3,
    BATCH_JOB_SIG       = 4,
    BATCH_HOST_INFO     = 5,
    BATCH_QUE_INFO      = 6,
    BATCH_GRP_INFO      = 7,
    BATCH_QUE_CTRL      = 8,
    BATCH_RECONFIG      = 9,
    BATCH_SHUTDOWN      = 10,
    BATCH_HOST_CTRL     = 11,
    BATCH_JOB_SWITCH    = 12,
    BATCH_JOB_MOVE      = 13,
    BATCH_JOB_MIG       = 14,
    BATCH_STATUS_JOB    = 15,
    BATCH_SLAVE_RESTART = 16,
    BATCH_USER_INFO     = 17,
    BATCH_PARAM_INFO    = 18,
    BATCH_JOB_MODIFY    = 19,
    BATCH_MULTIJOBS_SIG = 20,
    BATCH_JOB_MSG       = 21,
    BATCH_STATUS_MSG_ACK = 22,
    BATCH_DEBUG         = 23,
    BATCH_RESOURCE_INFO = 24,
    BATCH_RUSAGE_JOB    = 25,
    BATCH_JOB_FORCE     = 26,
    BATCH_JOBMSG_INFO   = 27,
    BATCH_JOBDEP_INFO   = 28,
    BATCH_JGRP_ADD      = 29,
    BATCH_JGRP_DEL      = 30,
    BATCH_JGRP_INFO     = 31,
    BATCH_JGRP_MOD      = 32,
} js_request_t;

typedef enum {
    JS_NEW_JOB_KEEP_CHAN = 0,
    JS_NEW_JOB	   	 = 1,
    JS_SWIT_JOB		 = 2,
    JS_MODIFY_JOB	 = 3,
    JS_SIG_JOB		 = 4,
    JS_PROBE		 = 5,
    JM_JOB_SETUP 	 = 6,
    CMD_JM_DEBUG	 = 7,
    CMD_JM_REBOOT 	 = 8,
    CMD_JM_SHUTDOWN 	 = 9,
    JM_GET_HOSTINFO	 = 10,
    JM_GET_RESOUINFO	 = 11,
    JM_LOAD_REQ		 = 12,
    JM_GET_INFO		 = 13,
    JM_GET_CLUSTERNAME	 = 14,
    JM_GET_MASTINFO	 = 15,
    JM_GET_CLUSINFO	 = 17,
    JM_LOAD_UPD		 = 18,
    JM_STATIC_INFO	 = 19,
    JM_ADD_HOST		 = 20,
    JM_RM_HOST		 = 21,
    JS_READY             = 22,
    CMD_START_TASK       = 23,
    CMD_JM_RECONFIG      = 24,
    JM_SIGNAL_TASK       = 25,
} jm_request_t;

typedef enum {
    BATCH_FILE_COPY = 1,
    BATCH_STATUS_TASK = 2,
} ee_request_t;

extern char *g_masterlist;
extern int g_conntimeout;
extern int g_recvtimeout;
extern int g_connretries;
extern int g_js_port;
extern int g_jm_port;

extern struct quickpoolInfo *gptrMyInfo;
extern struct sharedConf *gptrSharedConf;
extern struct clusterConf *gptrClusterConf;

#define SHELLLINE "#! /bin/sh\n\n"
#define CMDSTART "# QUICKPOOL: User input\n"
#define CMDEND "# QUICKPOOL: End user input\n"
#define ENVSSTART "# QUICKPOOL: Environments\n"
#define NUMENV "#QP_RM_HOST="
#define EDATASTART "# QUICKPOOL: edata\n"
#define AUXAUTHSTART "# QUICKPOOL: aux_auth_data\n"
#define EXITCMD "exit `expr $? \"|\" $ExitStat`\n"
#define WAITCLEANCMD "\nExitStat=$?\nwait\n# QUICKPOOL: End user input\ntrue\n"
#define TAILCMD "'; export "
#define TRAPSIGCMD "$QP_TRAPSIGS\n$QP_RCP1\n$QP_RCP2\n$QP_RCP3\n"
#define JOB_STARTER_KEYWORD "%USRCMD"

struct usedCoreInfo {
    LIST_T *forw;
    LIST_T *back;    
    int index;
    unsigned int job_count;  
    bool_t exclusive;
};

struct usedCoreInfoUp {
    int num;  
    LIST_T *used_index;
};

struct numaInfo {
    struct usedCoreInfoUp *numas;
    struct usedCoreInfoUp *sockets;
    LIST_T *cores;
};

struct nodeAffinity {
    struct numaInfo *alloc_numa;
};

struct conn_node {
    int conn_fd;
    char *node_name;
    char *firstnode_name;
    int firstnode_port;
    int node_rank;
    char *execute_user;
    char *cwd;
    JOBID_T jobid;
    char *script;
    unsigned int num_task;
    char **task_argv;
    pid_t pid;
    pid_t pgid;
    struct jobResourceUsage *inst_usage;
    time_t start_time;
    time_t end_time;
    STATUS_WAIT_T wait;
    int exit_code;
};

/* readconf.c */
extern struct QuickPoolParameter *readconf_parameter(void);
extern void initialize_settings(struct config_param *);
extern void initialize_threshold(unsigned int, struct resource_definition *, float [], float []);
extern struct hostConf *readconf_host(struct quickpoolInfo *, struct clusterConf *);
extern struct userConf *readconf_user(void);
extern struct queueConf *readconf_queue(struct quickpoolInfo *);
extern int add_hosttype(char *);

/* submitjob.c */
extern int set_jobfile_data(char *, char *, struct lenData *);
extern void unlink_delta_files(void);
extern void change_submit_request(struct request *, enum submitType);
extern int set_more_request(struct request *, enum submitType);
extern int setenv_for_submitext(struct lenData *, struct request *);

/* signal.c */
extern int string_2qpsignal(const char *);
extern void qpsignal_2string(int, char *);
extern int get_signal_value(int, char *);
extern bool_t is_terminate_signal(int);
extern bool_t suspend_terminate_defined(int *, const char *);

/* recordfile.c */
extern void clean_usage(struct rusage *);
extern int write_record(FILE *, struct record *);

/* pendingreason.c */
extern char *get_suspend_reason(int, int, struct resource_definition *);
extern char *get_pending_reason(int, int *, struct QuickPoolJobReply *,
                                struct resource_definition *);

/* remotetask.c */
extern int execute_task(struct conn_node *, int, int, int);
extern int send_signal_2task(struct conn_node *, int);

/* operatejob.c */
extern void dup_asked_hosts(struct submitRequest *, struct submitRequest *);
extern void copy_submit_request(struct submitRequest *, struct submitRequest *, JOBID_T);

#endif
